package com.homedo.odin.solution.service.bizservice.oms;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.homedo.common.redis.service.RedisService;
import com.homedo.core.common.base.dto.Meta;
import com.homedo.core.common.exception.BizException;
import com.homedo.core.common.util.BeanUtils;
import com.homedo.core.common.util.ParamCheckUtil;
import com.homedo.core.common.util.SensitiveWordUtil;
import com.homedo.odin.solution.contract.oms.CheckSensitiveWordReq;
import com.homedo.odin.solution.contract.oms.CheckSensitiveWordResp;
import com.homedo.odin.solution.contract.oms.ImportReq;
import com.homedo.odin.solution.contract.oms.SensitiveWordListResp;
import com.homedo.odin.solution.contract.oms.UpdateWordReq;
import com.homedo.odin.solution.enumcode.SqlEnum;
import com.homedo.odin.solution.enumcode.basic.DictTypeEnum;
import com.homedo.odin.solution.enumcode.other.RedisKeyEnum;
import com.homedo.odin.solution.model.dto.SensitiveWord;
import com.homedo.odin.solution.model.entity.DictData;
import com.homedo.odin.solution.service.DictDataServiceImpl;
import com.homedo.odin.solution.service.PoiServiceImpl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author: zhaoxudong
 * @date: 2018/3/7 19:06
 * @Description: 敏感词业务处理
 */
@Service
public class SensitiveWordBizService {

    private static final Logger logger = LoggerFactory.getLogger(SensitiveWordBizService.class);
    @Autowired
    DictDataServiceImpl dictDataService;
    @Autowired
    RedisService redisService;
    @Autowired
    private PoiServiceImpl poiService;

    public Set<String> findWordSet() {
        List<String> wordList = dictDataService
                .findValueListByType(DictTypeEnum.sensitiveWord.getType());
        return new HashSet<>(wordList);
    }

    public CheckSensitiveWordResp getSensitiveWord(CheckSensitiveWordReq request) {
        if (StringUtils.isBlank(request.getText())) {
            throw new BizException(Meta.CODE_451.getCode(), "校验文字不能为空");
        }
        //每次校验都要从redis里获取脏词列表
        Set<String> wordSet;
        wordSet = redisService.getSet(RedisKeyEnum.sensitive.name());
        if (wordSet == null || wordSet.isEmpty()) {
            //redis里没有，从数据库中取，并同步到redis里
            wordSet = findWordSet();
            redisService.addSet(RedisKeyEnum.sensitive.name(), wordSet);
        }
        CheckSensitiveWordResp resp = new CheckSensitiveWordResp();
        //初始化脏词库
        SensitiveWordUtil.init(wordSet);
        //判断脏词
        Set<String> text = SensitiveWordUtil.getSensitiveWord(request.getText());
        resp.setText(text);
        return resp;
    }

    /**
     * 查找脏词列表
     */
    public SensitiveWordListResp findSensitiveList(Integer pageNum, Integer pageSize, String value) {
        ParamCheckUtil.checkPageParam(pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<SensitiveWord> pageInfo = new PageInfo<SensitiveWord>(
                dictDataService.findSensitiveWord(DictTypeEnum.sensitiveWord.getType(), value));
        SensitiveWordListResp resp = BeanUtils.transfrom(SensitiveWordListResp.class, pageInfo);
        resp.setList(BeanUtils.batchTransform(SensitiveWord.class, resp.getList()));
        return resp;
    }

    /**
     * 导入脏词
     */
    public void importSensitiveWord(ImportReq req) {
        ParamCheckUtil.checkLongUserId(req.getUserId());
        if (StringUtils.isBlank(req.getUserName())) {
            throw new BizException(Meta.CODE_451.getCode(), "用户名字不能为空");
        }
        if (StringUtils.isBlank(req.getUrl())) {
            throw new BizException(Meta.CODE_451.getCode(), "url参数不能为空");
        }
        String url = req.getUrl();
        String userName = req.getUserName();
        Long userId = req.getUserId();
        //从文件服务器获取脏词列表
        Set<String> words;
        try {
            words = poiService.getSensitiveWordSet(url);
        } catch (IOException e) {
            logger.error("从文件服务器获取脏词列表失败", e);
            throw new BizException(Meta.CODE_500.getCode(), "从文件服务器获取脏词列表失败");
        }
        //没有脏词，直接返回
        if (words.isEmpty()) {
            return;
        }
        //保存
        List<DictData> dataList = new ArrayList<>();
        DictData data;
        for (String word : words) {
            data = new DictData();
            data.setCreatedBy(userId);
            data.setModifiedBy(userId);
            data.setCreatedName(userName);
            data.setModifiedName(userName);
            data.setKey(word);
            data.setValue(word);
            data.setType(DictTypeEnum.sensitiveWord.getType());
            dataList.add(data);
        }
        dictDataService.insertBatch(dataList);
        //存入redis
        try {
            redisService.addSet(RedisKeyEnum.sensitive.name(), words);
        } catch (Exception e) {
            logger.error("脏词插入redis失败", e);
        }
    }

    /**
     * 修改脏词
     */
    public void updateWord(UpdateWordReq request) {
        Long userId = request.getUserId();
        String original = request.getOriginal();
        String target = request.getTarget();
        String userName = request.getUserName();
        ParamCheckUtil.checkLongUserId(userId);
        if (StringUtils.isBlank(userName)) {
            throw new BizException(Meta.CODE_451.getCode(), "用户姓名不能为空");
        }
        if (StringUtils.isBlank(original)) {
            throw new BizException(Meta.CODE_451.getCode(), "原值不能为空");
        }
        if (StringUtils.isBlank(target)) {
            throw new BizException(Meta.CODE_451.getCode(), "修改之后的值不能为空");
        }
        Integer count = dictDataService
                .updateValueByValueAndType(userId, original, target, DictTypeEnum.sensitiveWord.getType(),
                        userName);
        if (count <= 0) {
            throw new BizException(SqlEnum.FAIL.getCode(), "没有更新任何数据");
        }
        //修改redis里面的值
        //1. 先移除
        redisService.removeSetValue(RedisKeyEnum.sensitive.name(), original);
        //2. 再增加
        Set<String> set = new HashSet<>();
        set.add(target);
        redisService.addSet(RedisKeyEnum.sensitive.name(), set);
    }

    public void updateWordStatus(String value, Long userId, String userName) {
        ParamCheckUtil.checkLongUserId(userId);
        if (StringUtils.isBlank(value)) {
            throw new BizException(Meta.CODE_451.getCode(), "脏词不能为空");
        }
        if (StringUtils.isBlank(userName)) {
            throw new BizException(Meta.CODE_451.getCode(), "用户名称不能为空");
        }
        Integer count = dictDataService
                .updateStatusByValueAndType(value, userId, DictTypeEnum.sensitiveWord.getType(), 1,
                        userName);
        if (count <= 0) {
            throw new BizException(SqlEnum.FAIL.getCode(), "删除失败");
        }
        //移除redis里面的值
        redisService.removeSetValue(RedisKeyEnum.sensitive.name(), value);
    }
}
